#ifndef ODBC_CONNECTION_HPP
#define ODBC_CONNECTION_HPP

#include "odbc/odbc_config.hpp"
#include "odbc/details/os_sql_wrapper.hpp"
#include <string>

namespace odbc
{
class environment;
	
	
/// \ingroup OdbcLibrary
/// \brief It encapsulates an odbc connection object, used to connect to a database.
///
/// The connection is established at object's construction time, so an exception can be thrown if the connection can't 
///	be set or can't be configured. The connection is automatically closed at destruction time. The commit operation is 
///	not done automatically. Therefore, explicit commit operation should be performed before the connection closing, in
/// order to apply the database changes.
///	\n
/// The created connection allows reading and writing to the database.\n
class ODBC_DECL connection
{
public:
	/// \brief It creates the odbc connection object and initializes it using the specified parameters.
	/// \param env the environment object required for creating the odbc connection. The connection class is a friend to 
	///		the environment class, in order to provide access to environment's private handle without having to publicly 
	///		expose it to other classes.
	/// \param connectionString the connection string to be used for creating the connection. For more details on how 
	///		the connection string should look like, please consult the odbc documentation.
	/// \param timeOut the time out to be used when connecting to the database. 
	/// \param hasAutocommit specifies whether an automatic commit is performed after the execution of each statement 
	///		(when parameter set to \c true) or thatthe commit is performed only explicitly.
	/// \throws odbc::odbc_error if the odbc connection configuration fails or the database connection can't be 
	///		established.
	connection( const environment& env, 
				const std::string& connectionString, 
				unsigned int timeOut,
				bool hasAutocommit = false);

	/// \brief It destroys the odbc connection object.
	virtual ~connection() throw();

	/// \brief It gets the auto commit status of the connection.
	/// \return true if the connection is set with autocommit or false otherwise.
	/// \exception odbc_error thrown if an error occurred during the ODBC API function calls.
	bool autocommit() const;

	/// \brief It performs an explicit commit.
	/// \details If the autocommit flag is set to true, the call of this method will have no effect, since the execution 
	///		statements will always be committed immediately after execution.
	/// \exception odbc_error thrown if an error occurred during the ODBC API function calls.
	void commit();

	/// \brief It performs an explicit rollback.
	/// \details If the autocommit flag is set to true, the call of this method will have no effect, since the execution 
	///		statements will always be committed immediately after execution.
	/// \exception odbc_error thrown if an error occurred during the ODBC API function calls.
	void rollback();

private:
	/// \brief It contains the handle to the odbc connection object.
	SQLHANDLE handle_;

	/// \brief The statement class is declared as friend of the connection class to allow it to access the enclosed 
	///		connection handle without having to make it accessible to other classes, too.
	friend class statement;

	/// \brief The error class is friend of the connection class, because it needs access to the handle of the 
	///		connection for getting diagnosis data. Friendship was preferred instead of making the handle publicly 
	///		accessible through an accessor.
	friend class odbc_error;

private:
	///	\brief It sets the autocommit attribute of the connection.
	/// \param on The value of the autocommit attribute (true if autocommit should be performed or false if explicit 
	///		commit should be specified).
	void set_autocommit( bool on);

private:
	connection( const connection& );
	connection& operator=( const connection& );
};

} // namespace odbc

#endif // ODBC_CONNECTION_HPP
